<template>
  <div class="elementForm">
    <el-form
        ref="ref"
        :hide-required-asterisk="asterisk"
        :model="form"
        :rules="rules"
        :size="size"
        :label-position="labelPosition"
        :label-width="labelWidth"
        :inline="inline"
    >
      <el-form-item
          v-for="(item, index) in formLabel"
          :key="index"
          :prop="item.prop"
          :label="item.label"
          :class="item.prop"
      >
        <span slot="label">
          <slot :name="item.prop + '-label'" />
          <!--  v-dompurify-html="item.label"  -->
          <span>{{ item.label }}</span>
        </span>

        <!-- input标签 -->
        <el-input
            v-if="item.type === 'input'"
            v-model="form[item.prop]"
            :type="item.inputType"
            :maxlength="item.maxlength"
            :minlength="item.minlength"
            :placeholder="item.placeholder"
            :show-word-limit="item['show-word-limit']"
            :rows="item.rows"
            :autosize="item.autosize"
            :disabled="item.disabled"
            :autocomplete="item.autocomplete"
            :size="item.size"
            :name="item.name"
            :readonly="item.readonly"
            :show-password="item['show-password']"
            :prefix-icon="item['prefix-icon']"
            :suffix-icon="item['suffix-icon']"
            :clearable="item.clearable"
        >
          <template :slot="item.slot">
            <slot :name="item.prop + '-input-slot'" :data="item.prop" />
          </template>
        </el-input>

        <!-- 计数器 -->
        <el-input-number
            v-if="item.type === 'inputNumber'"
            v-model="form[item.prop]"
            :disabled="item.disabled"
            :controls-position="item['controls-position']"
            :min="item.min"
            :max="item.max"
        />

        <!-- 表单之外的 -->
        <slot :name="item.prop" :data="form" />

        <!-- 单选 -->
        <el-radio-group :disabled="item.disabled" v-if="item.type === 'radio'" v-model="form[item.prop]">
          <el-radio :disabled="res.disabled" v-for="(res, i) in item.radio" :key="i" :label="res.val"> {{ res.name }} </el-radio>
        </el-radio-group>

        <!-- 下拉 -->
        <el-select
            v-if="item.type === 'option'"
            v-model="form[item.prop]"
            :disabled="item.disabled"
            :allow-create="item['allow-create']"
            :multiple="item['multiple']"
            :filterable="item['filterable']"
            :default-first-option="item['default-first-option']"
            :size="item.size"
            :placeholder="item.placeholder"
        >
          <el-option v-for="option in item.option" :key="option.value" :label="option.label" :value="option.value" :disabled="option.disabled"/>
        </el-select>

        <!-- 时间 -->
        <el-date-picker
            v-if="item.type === 'date'"
            v-model="form[item.prop]"
            :size="item.size"
            :disabled="item.disabled"
            :type="item.dateType"
            :value-format="item.valueFormat || 'yyyy-MM-dd'"
            :range-separator="item['range-separator'] || '至'"
            :start-placeholder="item['start-placeholder'] || '开始日期'"
            :end-placeholder="item['end-placeholder'] || '结束日期'"
            @change="changeDate"
        />


        <!-- 上传 -->
        <div v-if="item.type === 'upload'" class="uploadStyle">
          <!-- 单张  -->
          <div v-if="typeof form[item.prop] === 'string'" :class="`upload${item.prop} ${ form[item.prop] === '' ? '' : 'center' }`">
            <div class="centerImg">
              <div class="fileEdit" style="display:none;" id="string-fileEdit" @click="remove('string', item)">
                <span><i class="el-icon-delete"></i></span>
              </div>
              <img width="100%" :src="form[item.prop]" alt="">
            </div>
          </div>
          <!-- 多张  -->
          <div v-else :class="`upload${item.prop} centerList`">
            <div v-for="(chart, is) in form[item.prop]" :key="is" :class="`${item.prop}${is} container`">
              <div class="fileEdit" @click="remove('array', item, form[item.prop], is)">
                <span><i class="el-icon-delete"></i></span>
              </div>
              <img  width="100%" :src="chart.img" alt="">
            </div>
          </div>
          <el-upload
              ref="elUpload"
              :disabled="item.disabled"
              v-loading="item.loading"
              :upload-uid="item.prop"
              :headers="item.headers"
              :action="item.api"
              :multiple="item.multiple"
              :before-upload="beforeUpload"
              :drag="item.drag"
              :limit="item.limit"
              :on-success="function(res, file, list) { return onSuccess(res, file, list, item.prop, item.loading = false )}"
              :list-type="item['list-type']"
              :on-progress="() => { item.loading = false }"
              :on-error="() => { item.loading = false }"
              :on-exceed="function (file, list){
                return handleExceed(file, list, form[item.prop])
              }"
              :show-file-list="false"
          >
            <i class="el-icon-plus" />
          </el-upload>
        </div>

      </el-form-item>

      <el-form-item class="last-form-item">
        <slot name="button" />
      </el-form-item>

    </el-form>
  </div>
</template>
<script>
import Vue from 'vue'
export default Vue.extend({
  name: 'ElementForm',
  props: {
    form: { type: Object, default: () => { return {} } },
    formLabel: { type: Array, default: () => { return [] } },
    rules: { type: Object, default: () => { return {} } },
    labelPosition: { type: String, default: 'top' },
    labelWidth: { type: String, default: '150px' },
    inline: { type: Boolean, default: false },
    asterisk: { type: Boolean, default: false },
    upLoadName: { type: String, default: '' },
    token: { type: String, default: '' },
    size: { type: String, default: '' }
  },
  data() {
    return {
      date: [],
      loading: false
    }
  },
  computed: {
    // 组件的访问
    eleForm() {
      return this.$refs.ref
    },
    // 上传相关
    elUpload() {
      return this.$refs.elUpload
    }
  },
  methods: {
    // 获取时间
    changeDate() {
      this.form.date === null ? this.form.date = [] : this.form.date
      this.$emit('getDate', this.form)
    },
    // 验证
    formValidate() {
      return new Promise((resolve, reject) => {
        this.$refs.ref.validate((valid) => {
          if (valid) {
            resolve(this.form)
          } else {
            setTimeout(() => {
              reject('表单数据不合法！')
            }, 100)
          }
        })
      })
    },
    // 文件超出处理
    handleExceed(files, fileList, array){
      this.$emit('onExceed', files, array)
    },
    // 删除
    remove(type, val, array, index){
      const list = this.$refs.elUpload
      list.map(item => { item.clearFiles() })
      if (type === 'string'){
        let strFile = document.getElementById('string-fileEdit')
        strFile.style.display = 'none'
        this.form[val.prop] = ''
      }else {
        this.form[val.prop].splice(index, 1)
      }
    },
    // 上传之前 验证
    beforeUpload(file) {
      return (new Promise((resolve, reject) => {
        this.$emit('beforeUpload', file, resolve, reject)
      }))
    },
    // 图片上传成功
    onSuccess(res, file, fileList, name, load) {
      this.$emit('upLoad', res, name, load)
    },
    // 重置
    reset() {
      this.$refs.ref.resetFields()
    }
  }
})
</script>

<style lang="scss" scoped>
.elementForm{
  ::v-deep .el-form-item{
    .el-form-item__label {
      text-align-last: justify;
    }
    .el-select{
      width: 100%;
    }
    .date {
      .el-date-editor {
        width: 100%;
      }
    }
  }
  .last-form-item{
    text-align: left;
    ::v-deep .el-form-item__content{
      margin-left: 0 !important;
    }
  }
  $upWidth: 140px;
  $upHeight: 140px;
  ::v-deep .uploadStyle{
    display: flex;
    .el-upload{
      border: 1px #a8a9a9 dashed;
      width: $upWidth;
      height: $upHeight;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 8px;
    }
    .center{
      .centerImg{
        width: $upWidth;
        height: $upHeight;
        overflow: hidden;
        border: 1px dashed #C0CCDA;
        border-radius: 8px;
        margin-right: 5px;
        position: relative;
        cursor: pointer;
        .fileEdit{
          display: none
        }
        img{
          width: inherit;
          height: inherit;
        }
      }
      .centerImg:hover{
        .fileEdit{
          background: rgba(0,0,0,0.5);
          position: absolute;
          width: 100%;
          height: 100%;
          display: flex !important;
          align-items: center;
          justify-content: center;
          transition: all 0.3s;
          span{
            font-size: 25px;
            display: block;
            color: #ffffff;
          }
        }
      }
    }
    .centerList{
      display: flex;
      .container{
        margin-right: 5px;
        position: relative;
        width: $upWidth;
        height: $upHeight;
        overflow: hidden;
        border-radius: 8px;
        cursor: pointer;
        img{
          width: inherit;
          height: inherit;
        }
        .fileEdit{
          display: none;
        }
      }
      .container:hover{
        .fileEdit{
          background: rgba(0,0,0,0.5);
          position: absolute;
          width: 100%;
          height: 100%;
          display: flex !important;
          align-items: center;
          justify-content: center;
          transition: all 0.3s;
          span{
            font-size: 25px;
            color: #ffffff;
          }
        }
      }
    }
  }
}
</style>
